package com.ruoyi.eqmonitor.dispose.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.eqmonitor.dispose.domain.ExteriorSiteAlarm;
import com.ruoyi.eqmonitor.dispose.dtos.WaterQualityMergeDto;
import com.ruoyi.eqmonitor.dispose.dtos.WaterQualityMergeVO;
import com.ruoyi.eqmonitor.dispose.service.ExteriorSiteMonitorDataService;
import com.ruoyi.eqmonitor.dispose.service.IExteriorSiteAlarmService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 断面（微站）报警
 */
@Slf4j
@Component
@Profile("prod")
public class ExteriorSiteTask {

    @Resource
    private ExteriorSiteMonitorDataService siteMonitorDataService;

    @Resource
    private IExteriorSiteAlarmService exteriorSiteAlarmService;

    /**
     * 每4小时执行一次 判断断面是否报警
     */
    //@Scheduled(cron = "0 0 0/4 * * ?")
    public void callThePolice() {
        //获取断面实时数据并判断是否报警
        WaterQualityMergeDto waterQualityMergeDto = new WaterQualityMergeDto();
        waterQualityMergeDto.setState(6);
        Date date = new Date();
        waterQualityMergeDto.setBeginTime(DateUtils.getLastHour(date,4));
        waterQualityMergeDto.setEndTime(DateUtils.toString(date));
        List<WaterQualityMergeVO> waterQualityMerge = siteMonitorDataService.getWaterQualityMergeG(waterQualityMergeDto);
        //获取断面最近新增的报警
        List<ExteriorSiteAlarm> newestAlarm = exteriorSiteAlarmService.getNewestAlarm();
        if (waterQualityMerge != null){
            //报警不为空
            if (!newestAlarm.isEmpty()) {
                //过滤断面实时数据和断面最近新增的报警中断面id相同的数据
                List<WaterQualityMergeVO> list = waterQualityMerge.stream().parallel().filter(
                        a -> newestAlarm.stream().noneMatch(
                                b -> Objects.equals(a.getId(), b.getExteriorId()))).collect(Collectors.toList()
                );
                //新增从未报警的断面的报警
                saveAlarm(list);
                //删除上一步处理过的数据
                waterQualityMerge.removeAll(list);
                //修改报警
                updateAlarm(waterQualityMerge, newestAlarm);
            } else {
                //为空则新增
                saveAlarm(waterQualityMerge);
            }
        }else {
            //全部修改为非持续报警
            if (!newestAlarm.isEmpty()) {
                newestAlarm.forEach(n -> n.setPersistentStatus("否"));
                exteriorSiteAlarmService.updateBatchById(newestAlarm);
            }
        }
    }

    /**
     * 每天0点执行，删除60天之前的报警
     */
    //@Scheduled(cron = "0 0 * * * ?")
    public void del() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -60);
        Date targetDate = calendar.getTime();
        boolean remove = exteriorSiteAlarmService.remove(
                new LambdaQueryWrapper<ExteriorSiteAlarm>().le(ExteriorSiteAlarm::getLastAlarmTime, targetDate));
        if (!remove) {
            log.error("断面（微站）报警定时删除任务执行失败，时间条件：{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(targetDate));
        }
    }

    //新增报警
    private void saveAlarm(List<WaterQualityMergeVO> waterQualityMerge) {
        //超标则新增报警
        List<ExteriorSiteAlarm> list = waterQualityMerge.stream()
                .filter(WaterQualityMergeVO::getIfOverproofA)
                .map(vo -> {
                    ExteriorSiteAlarm alarm = new ExteriorSiteAlarm();
                    alarm.setExteriorId(vo.getId());
                    alarm.setExteriorName(vo.getSiteName());
                    alarm.setAreaName(vo.getAreaName());
                    alarm.setJzmz(vo.getJzmZ());
                    alarm.setNowjzmz(vo.getNowJzmZ());
                    alarm.setOverproof(vo.getOverproof());
                    alarm.setAdvalue(vo.getAdValue());
                    alarm.setZlvalue(vo.getZlValue());
                    alarm.setGmsyvalue(vo.getGmsyValue());
                    alarm.setX(vo.getX());
                    alarm.setY(vo.getY());
                    alarm.setAlarmTime(new Date());
                    alarm.setLastAlarmTime(new Date());
                    alarm.setPersistentStatus("是");
                    return alarm;
                }).collect(Collectors.toList());
        exteriorSiteAlarmService.saveBatch(list);
    }

    // 修改报警
    private void updateAlarm(List<WaterQualityMergeVO> waterQualityMerge, List<ExteriorSiteAlarm> newestAlarm) {
        List<ExteriorSiteAlarm> updateList = new ArrayList<>();
        List<WaterQualityMergeVO> saveList = new ArrayList<>();
        for (WaterQualityMergeVO vo : waterQualityMerge) {
            for (ExteriorSiteAlarm siteAlarm : newestAlarm) {
                if (vo.getId().equals(siteAlarm.getExteriorId())) {
                    handleAlarm(siteAlarm, vo, saveList, updateList);
                }
            }
        }
        saveAlarm(saveList);
        exteriorSiteAlarmService.updateBatchById(updateList);
    }

    // 处理报警
    private void handleAlarm(ExteriorSiteAlarm siteAlarm, WaterQualityMergeVO vo, List<WaterQualityMergeVO> saveList, List<ExteriorSiteAlarm> updateList) {
        String persistentStatus = siteAlarm.getPersistentStatus();//是否持续报警
        Date lastAlarmTime = siteAlarm.getLastAlarmTime();
        // 相差的时间
        int FOUR_HOURS_IN_SECONDS = 4 * 60 * 60;
        boolean isExceedFourHours = (new Date().getTime() - lastAlarmTime.getTime()) > FOUR_HOURS_IN_SECONDS * 1000;

        //判断是否持续报警
        if ("是".equals(persistentStatus)) {
            handlePersistentAlarm(siteAlarm, vo, updateList, saveList, isExceedFourHours);
        } else {
            saveList.add(vo);
        }
    }

    // 处理持续报警
    private void handlePersistentAlarm(ExteriorSiteAlarm siteAlarm, WaterQualityMergeVO vo, List<ExteriorSiteAlarm> updateList, List<WaterQualityMergeVO> saveList, boolean isExceedFourHours) {
        //判断最后报警时间和当前时间是否相差指定时间以上
        if (isExceedFourHours) {
            siteAlarm.setPersistentStatus("否");
            updateList.add(siteAlarm);
            saveList.add(vo);
        } else if (!vo.getIfOverproofA()) { //判断实时数据是否达标 达标 持续报警则修改为“否”
            siteAlarm.setPersistentStatus("否");
            updateList.add(siteAlarm);
        } else {    //超标 报警次数加一，更新最后报警时间、现状、超标因子、氨氮、总磷、高锰酸盐指数
            siteAlarm.setAlarmCount(siteAlarm.getAlarmCount() + 1);
            siteAlarm.setLastAlarmTime(new Date());
            siteAlarm.setNowjzmz(vo.getNowJzmZ());
            siteAlarm.setOverproof(vo.getOverproof());
            siteAlarm.setAdvalue(vo.getAdValue());
            siteAlarm.setZlvalue(vo.getZlValue());
            siteAlarm.setGmsyvalue(vo.getGmsyValue());
            updateList.add(siteAlarm);
        }
    }

}
